<template>
	<template
		v-if="linkOnly"
		:class="[
			'app-editor-container',
			'app-data-picker',
			`app-data-picker-${name}`,
		]"
	>
		<a @click="openLinkView">{{ value }}</a>
	</template>
	<template v-else-if="isAC && !isDropdown">
		<a-auto-complete
			:class="[
				'app-editor-container',
				'app-data-picker',
				`app-data-picker-${name}`,
			]"
			ref="autoComRef"
			:value="currentVal"
			:options="items"
			:open="open"
			dropdownClassName="app-editor-data-picker-dropdown"
			:disabled="disabled || readonly"
			@search="onSearch"
			@focus="onFocus"
			@blur="onBlur"
		>
			<template #option="option">
				<a-empty v-if="option.noData" :image="simpleImage" />
				<div v-else @click="onSelect(option[deKeyField])">
					{{ option[deMajorField] }}
				</div>
			</template>
			<a-input :placeholder="placeholder">
				<template #suffix>
					<CloseCircleOutlined
						v-show="value"
						class="suffix-icon"
						@click="clear"
					/>
					<DownOutlined
						v-show="!open"
						@click="switchAppAc"
						class="suffix-icon"
					/>
					<UpOutlined v-show="open" @click="switchAppAc" class="suffix-icon" />
					<SearchOutlined
						v-if="pickUpView && showButton"
						class="suffix-icon"
						@click="openView"
					/>
					<ExportOutlined
						v-if="linkView"
						class="suffix-icon"
						@click="openLinkView"
					/>
				</template>
			</a-input>
		</a-auto-complete>
	</template>
	<template v-else-if="noAC">
		<a-input
			:class="[
				'app-editor-container',
				'app-data-picker',
				`app-data-picker-${name}`,
			]"
			:value="value"
			:placeholder="placeholder"
		>
			<template #suffix>
				<CloseCircleOutlined
					v-show="value"
					class="suffix-icon"
					@click="clear"
				/>
				<SearchOutlined
					v-if="pickUpView && showButton"
					class="certain-category-icon"
					@click="openView"
				/>
				<LinkOutlined v-if="linkView" @click="openLinkView" />
			</template>
		</a-input>
	</template>
	<template v-else-if="isDropdown">
		<a-select
			:class="[
				'app-editor-container',
				'app-data-picker',
				`app-data-picker-${name}`,
			]"
			showSearch
			showArrow
			:mode="multiple ? 'multiple' : 'tag'"
			:value="currentVal"
			:disabled="disabled"
			:filterOption="false"
			@change="onChange"
			@search="onSearch"
			@focus="onFocus"
			@blur="onBlur"
			:placeholder="placeholder"
		>
			<template #suffixIcon v-if="linkView || pickUpView">
				<span class="app-data-picker-dropdown-select-icon">
					<CloseCircleOutlined
						v-show="value && !multiple"
						class="suffix-icon"
						@click="clear"
					/>
					<SearchOutlined
						v-if="pickUpView && showButton"
						class="certain-category-icon"
						@click="openView"
					/>
					<LinkOutlined v-if="linkView" @click="openLinkView" />
				</span>
			</template>
			<a-select-option
				v-for="(item, index) in items"
				:key="index"
				:value="item[deKeyField]"
			>
				{{ item[deMajorField] }}
			</a-select-option>
		</a-select>
	</template>
</template>
<script setup lang="ts">
import { Ref, ref } from 'vue';
import { Empty } from 'ant-design-vue';
import {
	SearchOutlined,
	ExportOutlined,
	CloseCircleOutlined,
	DownOutlined,
	UpOutlined,
	LinkOutlined,
} from '@ant-design/icons-vue';
import { IParam, IEvent, computedNavData } from '@/core';
import { dataPickerProps } from './data-picker';
import { handleEditorNavParams } from '@/hooks/use-editor';
import { deepCopy, isExistAndNotEmpty } from '@/core/utils';
interface EditorEmit {
	(name: 'component-action', value: IEvent<string>): void;
}
const props = defineProps(dataPickerProps);
const emit = defineEmits<EditorEmit>();
const { navContext, navViewParam } = handleEditorNavParams(props);
let items: Ref<any[]> = ref([]);
let searchVal: any = ref(undefined); //搜索值
let isSearch = ref(false); //管理搜索状态
let open = ref(false); //管理下拉展开状态
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
const autoComRef = ref();
let currentVal: Ref<any> = computed(() => {
	if (props.multiple) {
		if (props.value) {
			const selects: any = [];
			try {
				const _items = JSON.parse(props.value);
				_items.forEach((item: any) => {
					selects.push(item.srfkey);
				});
				if (items.value.length == 0) {
					items.value = _items;
				}
			} catch (error) {
				console.log(error);
			}
			return selects;
		}
	} else {
		if (isSearch.value) {
			return searchVal.value;
		} else {
			return props.value ? props.value : undefined;
		}
	}
});

/**
 * @description 填充外键值附加数据
 * @param item 选中数据
 */
const fillPickUpData = (item: IParam) => {
	if (props.pickUpData) {
		let pickUpDataArray: string[] = props.pickUpData.split(';');
		if (pickUpDataArray && pickUpDataArray.length > 0) {
			for (let i = 0; i < pickUpDataArray.length; i++) {
				if (item) {
					emit('component-action', {
						name: pickUpDataArray[i],
						action: 'valueChange',
						data: item[pickUpDataArray[i]],
					});
				} else {
					emit('component-action', {
						name: pickUpDataArray[i],
						action: 'valueChange',
						data: null,
					});
				}
			}
		}
	}
};

//自动填充失去焦点
const onBlur = () => {
	if(!props.multiple){
		searchVal.value = '';
		isSearch.value = false;
		open.value = false;
	}
};

//自动填充聚焦
const onFocus = () => {
	if (!isSearch.value) {
		searchVal.value = '';
		isSearch.value = true;
		if (props.isAC && !props.isDropdown) {
			items.value = [{ noData: true }];
		}
		open.value = true;
	}
	onSearch(searchVal.value);
};
/**
 * @description 自动填充搜索
 * @param value 搜索值
 */
const onSearch = (value: string) => {
	searchVal.value = value;
	let _navContext = deepCopy(navContext);
	let _navViewParam = deepCopy(navViewParam);
	const _data = computedNavData(
		props.data,
		_navContext,
		_navViewParam,
		props.localParam
	);
	Object.assign(_navViewParam, _data, { query: value, size: 1000 });
	if (props.sort) {
		Object.assign(_navViewParam, { sort: props.sort });
	}
	let _error: string = App.ts('common.generic.error', '错误');
	let requestException: string = App.ts(
		'common.generic.requestexception',
		'请求异常'
	);
	if (!props.service) {
		console.warn(App.ts('common.generic.noservice', '服务不存在'));
	} else if (!props.acParams) {
		console.warn(App.ts('common.generic.miss', '参数不存在'));
	} else {
		const { serviceName, interfaceName } = props.acParams;
		const { deKeyField, deCodeName } = props;
		props.service
			.getItems(
				serviceName,
				interfaceName,
				_navContext,
				_navViewParam,
				deKeyField,
				deCodeName
			)
			.then((response: any) => {
				if (!response) {
					console.warn(App.ts('common.generic.loadfail', '加载数据失败'));
					return;
				} else {
					open.value = true;
					if (props.isAC && !props.isDropdown && response.length == 0) {
						items.value = [{ noData: true }];
					} else {
						items.value = [...response];
					}
				}
			})
			.catch((error: any) => {
				const msg = error && error.message ? error.message : requestException;
				console.warn(msg);
			});
	}
};

//  自动填充选中
const onSelect = (value: any) => {
	const selectItem = items.value.find((item: IParam) =>
		Object.is(item[props.deKeyField], value)
	);
	switchAppAc();
	isSearch.value = false;
	autoComRef.value.blur();
	searchVal.value = '';
	emit('component-action', {
		name: `${props.name}`,
		action: 'valueChange',
		data: selectItem[props.deMajorField],
	});
	if (props.valueItem) {
		emit('component-action', {
			name: props.valueItem,
			action: 'valueChange',
			data: selectItem[props.deKeyField],
		});
	}
	fillPickUpData(selectItem);
};

//选择值改变
const onChange = (select: any, dateString: any) => {
	isSearch.value = false;
	if (props.multiple) {
		let selects: any = [];
		select.forEach((item: any) => {
			const selectItem = items.value.find((_item: IParam) =>
				Object.is(_item[props.deKeyField], item)
			);
			selects.push({
				srfkey: item,
				srfmajortext: selectItem ? selectItem[props.deMajorField] : undefined,
			});
		});
		emit('component-action', {
			name: props.name as string,
			action: 'valueChange',
			data: JSON.stringify(selects),
		});
	} else {
		let value_temp = items.value.find((_item: IParam) => {
			return Object.is(_item[props.deKeyField], select);
		});
		emit('component-action', {
			name: props.name as string,
			action: 'valueChange',
			data: value_temp ? value_temp[props.deMajorField] : undefined,
		});
		if (props.valueItem) {
			emit('component-action', {
				name: `${props.valueItem}`,
				action: 'valueChange',
				data: select,
			});
		}
	}
};
//关闭、打开弹窗
const switchAppAc = () => {
	open.value = !open.value;
};

//  自动填充清空值
const clear = (event: any) => {
	event.stopPropagation();
	event.preventDefault();
	emit('component-action', {
		name: `${props.name}`,
		action: 'valueChange',
		data: null,
	});
	if (props.valueItem) {
		emit('component-action', {
			name: props.valueItem,
			action: 'valueChange',
			data: null,
		});
	}
};

// 编辑器抛值
const doEditorEmit = (data: any[]): any => {
	if (props.multiple) {
		let selects: any[] = [];
		data.forEach((item: any, i: number) => {
			const index = items.value.findIndex((_item: any) =>
				Object.is(item[props.deKeyField], _item[props.deKeyField])
			);
			if (index < 0) {
				items.value.push(item);
			}
			selects.push({
				srfkey: item[props.deKeyField],
				srfmajortext: item[props.deMajorField],
			});
		});
		emit('component-action', {
			name: `${props.name}`,
			action: 'valueChange',
			data: JSON.stringify(selects),
		});
	} else {
		let majorValue: any = '';
		let keyValue: any = '';
		data.forEach((item: any) => {
			majorValue = item[props.deMajorField]
				? majorValue +
				  (majorValue ? props.separator : '') +
				  item[props.deMajorField]
				: majorValue +
				  (majorValue ? props.separator : '') +
				  item['srfmajortext'];
			keyValue = item[props.deKeyField]
				? keyValue + (keyValue ? props.separator : '') + item[props.deKeyField]
				: keyValue + (keyValue ? props.separator : '') + item['srfkey'];
		});
		if (props.valueItem) {
			emit('component-action', {
				name: props.valueItem,
				action: 'valueChange',
				data: keyValue,
			});
		}
		emit('component-action', {
			name: `${props.name}`,
			action: 'valueChange',
			data: majorValue,
		});
		return;
	}
};

//打开链接视图
const openLinkView = (event: any): void => {
	event.preventDefault();
	event.stopPropagation();
	if (
		!props.data ||
		!props.valueItem ||
		!props.data.hasOwnProperty(props.valueItem)
	) {
		const error = App.ts('common.generic.error', '错误');
		const formdataexception = App.ts(
			'common.datapicker.formdataexception',
			'表单数据异常！'
		);
		const valueitemexception = App.ts(
			'common.datapicker.valueitemexception',
			'值项异常'
		);
		if (!props.data) {
			console.error(formdataexception);
		} else {
			console.error(valueitemexception);
		}
		return;
	}
	if (!props.linkView) {
		return;
	}
	// 公共参数处理
	let data: any = {
		param: {},
		context: {},
	};
	Object.assign(data.param, navViewParam);
	Object.assign(data.context, navContext);

	// 参数处理
	let _context = data.context;
	let _param = data.param;
	Object.assign(_context, { [props.deKeyField]: props.data[props.valueItem] });

	const view = App.getAppViewConfig()?.[props.linkView];
	App.getOpenViewHelper().openPage(view, _context, _param);
};

// 打开一般视图
const openView = async (event: any) => {
	event.preventDefault();
	event.stopPropagation();
	if (props.disabled) {
		return;
	}
	if (!props.pickUpView) {
		return;
	}
	const view = App.getAppViewConfig()?.[props.pickUpView];
	if (!view) {
		return;
	}
	const params: IParam = {};
	const tempViewParams = deepCopy(navViewParam);
	//多选
	if (props.multiple) {
		let selectedData: IParam[] = [];
		try {
			selectedData = props.value ? JSON.parse(props.value) : [];
		} catch (error) {
			selectedData = [];
		}
		Object.assign(tempViewParams, { selectedData: selectedData });
	} else {
		const selectedData: IParam = {};
		if (
			props.data &&
			props.valueItem &&
			isExistAndNotEmpty(props.data[props.valueItem])
		) {
			Object.assign(selectedData, { srfkey: props.data[props.valueItem] });
		}
		if (isExistAndNotEmpty(`${props.value}`)) {
			Object.assign(selectedData, { srfmajortext: props.value });
		}
		Object.assign(tempViewParams, { selectedData: [selectedData] });
	}
	//打开视图
	if (
		!Object.is(view.openMode, 'POPOVER') &&
		!Object.is(view.openMode, 'DRAWER')
	) {
		Object.assign(params, { openMode: 'POPUPMODAL' });
	}
	const result = await App.getOpenViewHelper().openModal(
		view,
		deepCopy(navContext),
		tempViewParams
	);
	if (result && result.ok) {
		doEditorEmit(result.data as Array<any>);
	}
};
</script>
